// 转换日期格式
export function formatDate(time: string, format = 'YY-MM-DD hh:mm:ss') {
  const date = new Date(time) // 如果接受的是一个Date对象-转化有误差
  const year = date.getFullYear()
  const month = date.getMonth() + 1 // 月份是从0开始的
  const day = date.getDate()
  const hour = date.getHours()
  const min = date.getMinutes()
  const sec = date.getSeconds()
  // eslint-disable-next-line prefer-spread
  const preArr = Array.apply(null, Array(10)).map((_, index) => {
    return `0${index}`
  }) // 开个长度为10的数组 格式为 00 01 02 03
  const newTime = format
    .replace(/YY/g, `${year}`)
    .replace(/MM/g, preArr[month] || `${month}`)
    .replace(/DD/g, preArr[day] || `${day}`)
    .replace(/hh/g, preArr[hour] || `${hour}`)
    .replace(/mm/g, preArr[min] || `${min}`)
    .replace(/ss/g, preArr[sec] || `${sec}`)
  return newTime
}

export function greetTime() {
  const time = new Date()
  const hour = time.getHours()
  return hour < 9
    ? '早上好'
    : hour <= 11
      ? '上午好'
      : hour <= 13
        ? '中午好'
        : hour < 20
          ? '下午好'
          : '晚上好'
}

// 按照对象属性分类
export function groupByObj(arr: Record<string, any>[], prop: string) {
  const ret = {} as any
  for (const item of arr) {
    const key = item[prop]
    if (!ret[key])
      ret[key] = []

    ret[key].push(item)
  }
  return ret
}

// 按照数组属性分类
export function groupByArr(arr: any[], index: number) {
  const ret = {} as any
  for (const item of arr) {
    const key = item[index]
    if (!ret[key]) {
      ret[key] = {
        name: key,
        data: [],
      }
    }
    ret[key].data.push(item.slice(0, 2))
  }
  return Object.values(ret)
}

// 找到当前节点的所有的上层父节点
export function getParentKeys(tree: any[], nodeId: string) {
  const path: string[] = []
  const searchKey: any = function (tree: any, nodeId: string) {
    for (let i = 0; i < tree.length; i++) {
      const data = tree[i]
      // path.push(data.id)
      path.push(data)
      if (data.id === nodeId)
        return path
      if (data.children) {
        const findChildren = searchKey(data.children, nodeId)
        if (findChildren)
          return findChildren
      }
      // 一轮没有返回就需要把push的id给移除->此路不正确
      path.pop()
    }
  }
  searchKey(tree, nodeId)
  return path
}

export function arrayToTree(arr: Record<string, any>[], pid: string | number): any {
  const ret = []
  for (const item of arr) {
    if (item.pid === pid)
      ret.push({ ...item, children: arrayToTree(arr, item.id) })
  }
  return ret
}

export function treeToArray(tree: { children?: [], item: any }, ret: any[] = []) {
  const { children, ...item } = tree as any
  ret.push(item)
  if (children.length > 0) {
    for (const child of children)
      treeToArray(child, ret)
  }
  return ret
}

// isEmptyObject({}) // true
// isEmptyObject({a:"not empty"}) // false
export function isEmptyObject(obj: Record<string, any>) {
  return Reflect.ownKeys(obj).length === 0 && obj.constructor === Object
}

// 拿到query对象
export function getQueryFromSearch(params: string = window.location.search) {
  if (params.length === 0)
    return {}
  return decodeURIComponent(params)
    .replace(/(^\?)/, '')
    .split('&')
    .reduce((searchParams: any, keyValuePair: any) => {
      keyValuePair = keyValuePair.split('=')
      searchParams[keyValuePair[0]] = Number(keyValuePair[1])
      return searchParams
    }, {})
}

// 对象转为query字符串
export function transformObjToString(params: Record<string, any>) {
  const queryString = Object.keys(params)
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    .join('&')
  return queryString
}

/**
 * @description base64下载pdf/execl文件
 * @param {string} base64 编码
 * @param {string} fileName 文件名
 * @param {string} fileType 文件类型,类似txt，word...
 */
export function downloadFile(base64: string, fileName: string, fileType: string) {
  // data就是后台返回的base64的 文件流
  interface fileSteamType {
    bstr?: string
  }
  const fileSteam: fileSteamType = {
    bstr: atob(base64),
  }
  let n = fileSteam.bstr!.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    // bstr的unicode编码
    u8arr[n] = fileSteam.bstr!.charCodeAt(n)
  }
  const URL = new Blob([u8arr], {
    type: fileType,
  })
  const reader = new FileReader()
  reader.readAsDataURL(URL)
  reader.onload = function (e) {
    // 兼容IE
    if ((window.navigator as any).msSaveOrOpenBlob) {
      // const bstr = atob((e.target!.result as string).split(',')[1])
      const bstr = atob(base64)
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--)
        u8arr[n] = bstr.charCodeAt(n)

      const blob = new Blob([u8arr]);
      (window.navigator as any).msSaveOrOpenBlob(blob, `${fileName}.${fileType}`)
    }
    else {
      // 转换完成，创建一个a标签用于下载
      const a = document.createElement('a')
      a.download = `${fileName}.${fileType}`
      a.href = e.target!.result as string
      a.setAttribute('id', 'export')
      // 解决firefox不能触发a.click
      const evt = document.createEvent('MouseEvents')
      evt.initEvent('click', true, true)
      a.dispatchEvent(evt)
    }
  }
  delete fileSteam.bstr
}

// 文件大小单位转换
export function formatFileSizeUnits(kb: number) {
  const units = ['KB', 'MB', 'GB', 'TB', 'PB']
  let unitIndex = 0

  while (kb >= 1024 && unitIndex < units.length - 1) {
    kb /= 1024
    unitIndex++
  }

  return `${kb.toFixed(2)} ${units[unitIndex]}`
}

// 将base64转换为File
export function Base64toFile(base64: string, filename: string) {
  const bstr = window.atob(base64)
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--)
    u8arr[n] = bstr.charCodeAt(n)

  return new File([u8arr], filename)
}

// 将File转换为base64
export function FileToBase64(file: any) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file.originFileObj)
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
  })
}

// 将 base64 数据转换为 Blob 对象
export function b64toBlob(b64Data: string, contentType = '', sliceSize = 512) {
  const byteCharacters = atob(b64Data)
  const byteArrays = []

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize)

    const byteNumbers: any = Array.from({ length: slice.length })
    for (let i = 0; i < slice.length; i++)
      byteNumbers[i] = slice.charCodeAt(i)

    const byteArray = new Uint8Array(byteNumbers)
    byteArrays.push(byteArray)
  }

  const blob = new Blob(byteArrays, { type: contentType })
  return blob
}

export const FormSearchFilter = (input: string, option: any) => option.label.toLowerCase().includes(input.toLowerCase())

// 横向数据和纵向数据调换
export function hvTransformArray(arr: any[]) {
  // 获取二维数组的行数和列数
  let rows = arr.length
  const cols = arr[0]?.length

  // 创建一个新的二维数组用于存储互换后的结果
  const dimensionArray = [] as any

  // 遍历原始二维数组，将横纵坐标互换后的元素存入新数组
  for (let i = 0; i < cols; i++) {
    dimensionArray.push([])
    for (let j = 0; j < rows; j++)
      dimensionArray[i].push(arr[j][i])
  }

  // 用不到变量设置为null方便回收
  rows = null as any

  return dimensionArray
}

// 从文件名中截取最后一个点号之后的部分
export function getExtension(name: string) {
  return name.substring(name.lastIndexOf ('.') + 1)
}

export function removeEmptyInObject(obj: Record<string, any>) {
  return Object.entries(obj).reduce((acc: Record<string, any>, [key, value]) => {
    if (value !== null && value !== '' && value !== undefined)
      acc[key] = value

    return acc
  }, {})
}

export function credentialsFetch(url: any, options: any) {
  return window.fetch(url, { ...options, credentials: 'omit' })
}
